/*
* Copyright 2009 NOR_/D Labs <http://labs.nortd.com>
*
* This file is part of SceneExpression.
* SceneExpression is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License 
* as published by the Free Software Foundation, either version 3 of 
* the License, or (at your option) any later version. For details
* see <http://www.gnu.org/licenses/>.
*
* * *
* 
*/

#ifndef SX_WIDGET
#define SX_WIDGET


#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Material>
#include <osg/Vec3>
#include <osg/MatrixTransform>
#include <osgText/Text>
#include <osg/LineWidth>

#include "sxConstants.h"
#include "sxTypes.h"
#include "sxNode.h"
#include "sxEvents.h"




class sxWidget: public sxNode {

    public:  
      
        sxWidget();    
        virtual void reshape();
        void setName( std::string name);
        std::string getName();
        virtual void setZIndex(long zIndex);
        virtual long getZIndex();
        virtual void setShape( float width, float height);
        virtual float getWidth();
        virtual float getHeight();
        
        void setBackgroundColor( osg::Vec4 color );
        void setBackgroundColor( float r, float g, float b, float a=1.0f );
        osg::Vec4 getBackgroundColor();
        void setBorderColor( osg::Vec4 color );
        void setBorderColor( float r, float g, float b, float a=1.0f );
        osg::Vec4 getBorderColor();
            
        void setXY( const osg::Vec3& pnt ); // convinience method for setting pos in the x,y plane
        void addXY( const osg::Vec3& pnt ); // convinience method for adding to pos in the x,y plane
        
        bool isDragging(sxTouch& touch);
        osg::Vec3 getVelocity( sxTouch& touch );
        osg::Vec3 getWorldVelocity( sxTouch& touch );   

        void setPosition( float x, float y, float z=0.0f);
        using sxNode::setPosition;

        virtual void update() {}
        
        virtual bool touchDown( sxTouch& touch );
        virtual bool touchMove( sxTouch& touch );
        virtual bool touchUp( sxTouch& touch );
        
        bool touchDownInternal( sxTouch& touch );
        bool touchMoveInternal( sxTouch& touch );
        bool touchUpInternal( sxTouch& touch );      
        
        float rangemap(float r1val, float r1min, float r1max, float r2min, float r2max); 

      
    protected:
      
        float _width, _height; //there is no intrinsic boundary
                               //hint: backgroundVertices can be generated in regard to them
        long _zIndex;
        std::map<int,sxTouch*>  _activeTouches;
        std::map<sxTouch*,osg::Vec3>  _touchDownLocalPosition;  //keep track where the touch came
        std::map<sxTouch*,osg::Vec3>  _lastLocalPosition;  //keep track of previous hits, by touch
        
        
        osg::ref_ptr<osg::Geometry>    _backgroundGeometry;    
        osg::ref_ptr<osg::Vec3Array>   _backgroundVertices;
        osg::ref_ptr<osg::DrawArrays>  _backgroundDrawArray;
        osg::ref_ptr<osg::Vec4Array>   _backgroundColors;
        osg::ref_ptr<osg::Vec3Array>   _backgroundNormals;

        osg::ref_ptr<osg::Geometry>    _borderGeometry;    
        osg::ref_ptr<osg::DrawArrays>  _borderDrawArray;
        osg::ref_ptr<osg::Vec4Array>   _borderColors;
        
        osg::ref_ptr<osg::PositionAttitudeTransform>  _pickXform;
        osg::ref_ptr<osg::Geode>                      _pickGeode;
        osg::Vec3 velocity;
        bool _bDragging;
        
        void addRoundedRect( float x, float y, float w, float h, float r, osg::Vec3Array* vertices );
        void roundedCorner( float x, float y, float pivotX, float pivotY, osg::Vec3Array* vertices ); 

};




#endif